"""
预约服务模块
"""
import random
import time
from typing import Dict, List, Tuple, Optional
from config.settings import SERVICES, EMAIL_CONFIG
from utils.network import network_client
from utils.logger import logger
from utils.audio import audio_player
from utils.mail import mail_sender
from utils.date_utils import date_utils


class AppointmentService:
    """预约服务类"""
    
    def __init__(self, user_id: str = None):
        self.services = SERVICES
        self.user_id = user_id or 'default'
        # 为每个用户创建独立的网络客户端
        from utils.network import NetworkClient
        from config.settings import SYSTEM_CONFIG
        debug_config = SYSTEM_CONFIG.get('debug', {})
        network_debug = debug_config.get('network_requests', False)
        self.network_client = NetworkClient(debug=network_debug, user_id=user_id)
    
    def scan_available_slots(self, name: str, service_name: str, 
                           safe_dates: List[str]) -> Tuple[Dict, List[str]]:
        """扫描可用时间段"""
        try:
            service_info = self.services[service_name]
            service_id = service_info['service_id']
            calendar_id = service_info['calendar_id']
            duration = service_info['duration']
            
            calendar_items = {}
            available_slots = []
            
            start_time = time.time()
            
            for date in safe_dates:
                logger.log(f'{name}:正在扫描当前日期:[{date}]', name)
                
                # 获取时间段（使用配置的calendar_id）
                timeslots_data = self.network_client.get_timeslots(
                    service_id, duration, date, use_range_search=False, calendar_id=calendar_id
                )
                
                if not timeslots_data:
                    continue
                
                # 处理时间段数据
                for slot in timeslots_data:
                    if slot.get('calendarid') and slot['calendarid'] != '':
                        logger.log(f'当天结果{slot["start"]}-{slot["end"]}', name)
                        
                        # 获取具体时间段，使用配置的calendar_id
                        time_slots = self.network_client.get_timeslots(
                            service_id, duration, slot['start'].split('T')[0], 
                            use_range_search=False, calendar_id=calendar_id
                        )
                        
                        if time_slots:
                            for time_slot in time_slots:
                                combined_time = f"{time_slot['start']}@{time_slot['end']}"
                                calendar_items[combined_time] = {
                                    'calendarid': time_slot['calendarid'],
                                    'calname': time_slot.get('calname', time_slot.get('calendarname', ''))
                                }
                                available_slots.append(combined_time)
                                logger.log(
                                    f'{time_slot["start"].split("T")[1]}-{time_slot["end"].split("T")[1]}', 
                                    name
                                )
                
                network_client.add_delay(1, 2)  # 添加延迟避免请求过快
            
            end_time = time.time()
            logger.log(f'{name}:扫描完成，耗时 {end_time - start_time:.2f} 秒', name)
            
            return calendar_items, available_slots
            
        except Exception as e:
            logger.log(f'{name}:扫描失败 - {e}', name)
            return {}, []
    
    def book_appointment(self, candidate_info: List[str], start_time: str, 
                        end_time: str, service_name: str, 
                        calendar_item: Dict, service_text: str = None) -> bool:
        """预约时间段"""
        try:
            anrede, first_name, last_name, address, zip_code, email, birthday, phone = candidate_info
            
            # 格式化时间
            start_formatted = start_time.replace('T', ' ')[:16]
            end_formatted = end_time.replace('T', ' ')[:16]
            
            # 生成预约组ID
            appgroup = f'31a94a6f-{str(random.random())[2:6]}-4770-9fe5-2bbe554eebbd'
            
            # 构建预约信息（根据curl请求格式）
            bookerinfo = f"""Anrede\t{anrede}\r\nVorname\t{first_name}\r\nName\t{last_name}\r\nE-Mail\t{email}\r\nGeburtsdatum\t{birthday}\r\n\t\r\nTerminerinnerung\t8 Stunden vor Termin\r\n"""
            
            service_id = self.services[service_name]['service_id']
            
            # 如果没有提供服务文本，使用配置中的文本
            if not service_text:
                service_text = self.services[service_name].get('text', f"Service {service_name}")
            
            # 构建请求数据
            booking_data = self._build_booking_data(
                first_name, last_name, email, birthday, address, zip_code, 
                phone, anrede, bookerinfo, calendar_item, start_formatted, 
                end_formatted, service_id, appgroup, service_text
            )
            
            # 发送预约请求
            response = self.network_client.book_appointment(booking_data)
            
            if response and (response.get('Status') == 200 or response.get('Status') == '200'):
                # 保存成功数据
                self._save_booking_data(response)
                audio_player.play_success()
                
                # 更新预约状态为已完成
                self._update_appointment_status(start_time, end_time)
                
                logger.log(f'{first_name}:预约成功！请在2小时内检查邮箱并验证！', first_name)
                return True
            else:
                logger.log(f'{first_name}:预约失败 - {response}', first_name)
                return False
                
        except Exception as e:
            logger.log(f'{first_name}:预约异常 - {e}', first_name)
            return False
    
    def _build_booking_data(self, first_name: str, last_name: str, email: str,
                           birthday: str, address: str, zip_code: str, phone: str,
                           anrede: str, bookerinfo: str, calendar_item: Dict,
                           start: str, end: str, service_id: str, appgroup: str,
                           service_text: str = None) -> str:
        """构建预约请求数据"""
        from config.settings import BOOKING_CONFIG
        
        # 处理可选字段
        street = address if address else ''
        zip_val = zip_code if zip_code else ''
        city = 'Duisburg' if address else ''  # 如果有地址则使用Duisburg，否则为空
        phone_val = phone if phone else ''
        
        # 构建服务文本（如果未提供则使用默认）
        if not service_text:
            service_text = f"Service {service_id}"
        
        # 构建服务容量详情
        services_capacity_details = f"{service_text}\t1\r\n"
        
        # 构建基础参数
        params = []
        for key, value in BOOKING_CONFIG.items():
            params.append(f"{key}={value}")
        
        # 添加动态参数
        params.extend([
            f"services={service_id}",
            f"servicestext={self.network_client.encode_string(service_text)}",
            f"servicesinclsgtext={self.network_client.encode_string(service_text)}",
            f"FirstName={self.network_client.encode_string(first_name)}",
            f"LastName={self.network_client.encode_string(last_name)}",
            f"Email={self.network_client.encode_string(email)}",
            f"Birthday={self.network_client.encode_string(birthday)}",
            f"Street={self.network_client.encode_string(street)}",
            f"ZIP={zip_val}",
            f"City={city}",
            f"Phone={phone_val}",
            f"Salutation={anrede}",
            f"bookerinfo={self.network_client.encode_string(bookerinfo)}",
            f"calendarname={self.network_client.encode_string(calendar_item['calname'])}",
            f"start={start}",
            f"end={end}",
            f"calendarid={calendar_item['calendarid']}",
            f"calname={self.network_client.encode_string(calendar_item['calname'])}",
            f"location=Sonnenwall%2073-75%2C%2047051%20Duisburg",  # 根据curl请求更新地址
            f"appgroup={self.network_client.encode_string(appgroup)}",
            f"servicescapacity={{\"{service_id}\":\"1\"}}",
            f"servicescapacitydetails={self.network_client.encode_string(services_capacity_details)}"
        ])
        
        return "&".join(params)
    
    def _save_booking_data(self, data: Dict):
        """保存预约数据"""
        try:
            with open("data/data.txt", 'a', encoding='utf-8') as f:
                f.write(str(data) + '\n')
        except Exception as e:
            logger.log(f'保存数据失败: {e}', 'system')
    
    def _update_appointment_status(self, start_time: str, end_time: str):
        """更新预约状态为已完成"""
        try:
            # 导入全局变量
            import sys
            import os
            sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
            from app import confirmed_requests
            from datetime import datetime
            
            # 查找对应的请求并更新状态
            for request_id, request_data in confirmed_requests.items():
                if request_data.get('user_id') == self.user_id:
                    request_data['status'] = 'completed'
                    request_data['appointment_date'] = start_time.split('T')[0]  # 提取日期部分
                    request_data['appointment_time'] = f"{start_time.split('T')[1][:5]} - {end_time.split('T')[1][:5]}"
                    request_data['completed_at'] = datetime.now()
                    logger.log(f'预约状态已更新为已完成: {request_id}', 'system')
                    break
        except Exception as e:
            logger.log(f'更新预约状态失败: {e}', 'system')


# 全局预约服务实例
appointment_service = AppointmentService()
